
#define __SPI_F_C__

//#include <msp430f5502.h>
#include "spi_f.h"
#include "Display_EPD_W21_spi.h"
//#include "delay.h"
//#include "pindefine.h"

//**********************************
//      MSP430f550x port define
//**********************************
//OUTPUT
//#define MFCSB_H  P5OUT_bit.P5OUT1
//#define MFCSB_L  P5OUT&=0xFD
//#define MFCSB_H  P5OUT|=0x02
//#define MFDO  P2OUT_bit.P2OUT0
//#define MFDO 	P2IN_bit.P2IN0

void spi_flash_init(void)
{
  MFCSB_H;
}

void spi_flash_tx(unsigned char dat)
{
  unsigned char i;
  
  for(i=0;i<8;i++)
  {
    if(dat & 0x80) 
    {SDA_H;}
    else 
    {SDA_L;}
    delay(1);
    SCL_H;
    delay(1);    
    SCL_L;  
    dat=dat<<1;
  }
  SDA_L;
  delay(1); 
}

unsigned char spi_flash_rx(void)
{
  int i;
  unsigned char DATA_BUF=0x00;

  for(i=0;i<8;i++)
  {
    DATA_BUF=DATA_BUF<<1;
    SCL_L;
    if(MFDO) DATA_BUF|=0x01;     
    SCL_H;
    delay(1);
  }
  SCL_L;
  SDA_L;
  
  delay(1);  


  return DATA_BUF;
}

void Command_F(unsigned char command)
{
  MFCSB_L;
  spi_flash_tx(command);
  MFCSB_H;
}

void Write_Enable_F(void)
{
  Command_F(0x06);
}

void Write_Disable_F(void)
{
  Command_F(0x04);
}





unsigned char Read_Status_F(void)
{
  unsigned char DATA_BUF=0x00;
  MFCSB_L;
  spi_flash_tx(0x05);
  DATA_BUF = spi_flash_rx();
  MFCSB_H;
  return DATA_BUF;
}

void Write_Status_F(unsigned char BUF)
{
  Write_Enable_F();
  
  spi_flash_tx(0x01);
  spi_flash_tx(BUF);
  while(Read_Status_F()&0x01!=0x00);  
}

//*************************************************

void Protect_Upper_Memory_F(void)
{
  if(Read_Status_F()!=PROTECT_UPPER_F) Write_Status_F(PROTECT_UPPER_F);
}

void Protect_Lower_Memory_F(void)
{
  if(Read_Status_F()!=PROTECT_LOWER_F) Write_Status_F(PROTECT_LOWER_F);
}

void Protect_All_Memory_F(void)
{
  if(Read_Status_F()!=PROTECT_ALL_F) Write_Status_F(PROTECT_ALL_F); 
}

void Cancel_Memory_Protect_F(void)
{
  if(Read_Status_F()!=CANCEL_PROTECT_F) Write_Status_F(CANCEL_PROTECT_F);
}

//*************************************************
void Send_Address_F(unsigned char address_23_16, unsigned int address_15_0)
{

  spi_flash_tx(address_23_16);

  spi_flash_tx((unsigned char)(address_15_0 >> 8));

  spi_flash_tx((unsigned char)address_15_0);
}

void Erase_F(unsigned char command, unsigned char address_23_16, unsigned int address_15_0)
{
  Write_Enable_F();
  MFCSB_L;
  spi_flash_tx(command);
  Send_Address_F(address_23_16,address_15_0);
  MFCSB_H;
  while(Read_Status_F()&0x01!=0x00);
}
unsigned char Section_Erase_F(unsigned char address_23_16, unsigned int address_15_0)
{
  Erase_F(0x20,address_23_16,address_15_0);
  if(Read_Status_F()==0x80) return SPI_DONE_F;
  else return SPI_ERROR_F;
}

unsigned char Block_Erase_F(unsigned char address_23_16, unsigned int address_15_0)
{
  Erase_F(0xD8,address_23_16,address_15_0);
  if(Read_Status_F()==0x80) return SPI_DONE_F;
  else return SPI_ERROR_F;
}

unsigned char Page_Program_F(unsigned char address_23_16, unsigned int address_15_0, unsigned char const *write_data, unsigned int counter)
{
  unsigned int idx,idx_256;
  

  for(idx_256=0;idx_256<counter/256;idx_256++)
  {
    Write_Enable_F();    
    MFCSB_L;

    spi_flash_tx(0x02);
    Send_Address_F(address_23_16,address_15_0 + idx_256*256);
    for(idx=0;idx<256;idx++)
    {
      spi_flash_tx(*write_data);
      write_data++;
    }
 
    MFCSB_H;
    while(Read_Status_F()&0x01!=0x00);
  }
  
  if(counter%256 > 0)
  {
    Write_Enable_F();
    MFCSB_L;

    spi_flash_tx(0x02);
    Send_Address_F(address_23_16,address_15_0 + counter&0xFF00);
    for(idx=0;idx<counter%256;idx++)
    {
      spi_flash_tx(*write_data);
      write_data++;
    }

    MFCSB_H;
    while(Read_Status_F()&0x01!=0x00);
  }
  
  if(Read_Status_F()==0x80) return SPI_DONE_F;
  else return SPI_ERROR_F;   
}
//********************************************************************************

void ReadData_F(unsigned char address_23_16, unsigned int address_15_0, unsigned char *read_data, unsigned int counter)
{
  unsigned int i;
  MFCSB_L;

  spi_flash_tx(0x03);
  Send_Address_F(address_23_16,address_15_0);
  for(i=0;i<counter;i++)
  {

    
    *read_data=spi_flash_rx();

    read_data++;
  }

  MFCSB_H;  
}
